/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.nac.tbot;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.sun.org.apache.bcel.internal.generic.NEW;

import net.nac.tbot.eltetris.Board;
import net.nac.tbot.eltetris.Bot;
import net.nac.tbot.eltetris.Move;
import net.nac.tbot.eltetris.TetraminoFactory;

/**
 *
 * @author DTIT
 */
public class TetrisBattleBoard {

  private final Point origin;
  public final Dimension dimension = new Dimension(10 * 18, 20 * 18);
  public Point nextPoint1;
  public Point nextPoint2;
  public Point nextPoint3;
  private Rectangle rect;
  private Robot robot;
  private Timer timer;
  private final int lightBlack = new Color(47, 47, 47).getRGB();
  private final int lightestBlack = new Color(77, 77, 77).getRGB();
  private final int darkBlack = new Color(43, 43, 43).getRGB();
  private State state = State.STANDBY;
  private int current = -1;
  private int hold = -1;
  private int next = -1;
  private int delay = 60;
  private boolean pressedShift = false;
  private Bot bot;
  private Move currentMove = null;
  private int gridHeight = 18;
  private int gridWidth = 18;
  private int[] board = new int[20];
  private int[] lastBoard = null;

  public TetrisBattleBoard(int x, int y) {
    origin = new Point(x, y + 2);
    rect = new Rectangle(origin, dimension);
    nextPoint1 = new Point(origin.x + 220, origin.y + 53);
    nextPoint2 = new Point(origin.x + 225, origin.y + 53);
    nextPoint3 = new Point(origin.x + 225, origin.y + 46);
    try {
      robot = new Robot();
    } catch (AWTException ex) {
      Logger.getLogger(TetrisBattleBoard.class.getName()).log(Level.SEVERE, null, ex);
    }
    TimerTask task = new BoardCheck();
    timer = new Timer();
    timer.schedule(task, 0, 20);
  }

  private class BoardCheck extends TimerTask {

    @Override
    public void run() {

      switch (state) {
        case STANDBY:
          standBy();
          break;
        case SENDING_PIECE:
          sendingPiece();
          break;
      }

//      System.out.println(state);
    }
  }

  private void standBy() {
    int blankcount = 0;
    BufferedImage image = robot.createScreenCapture(rect);
    for (int i = 1; i < 21; i++) {
      for (int j = 1; j < 11; j++) {
        int px = j * gridWidth - 9;
        int py = i * gridHeight - 9;

        int rgb = image.getRGB(px, py);

        if (rgb == lightBlack || rgb == darkBlack || rgb == lightestBlack) {
          blankcount++;
        }
      }
    }
    if (blankcount == 200) {
      state = State.SENDING_PIECE;
      hold = -1;
      current = -1;
      next = -1;
      pressedShift = false;
    }
  }

  private void getCurrent() {
    BufferedImage image = robot.createScreenCapture(rect);

    for (int j = 5; j < 8; j++) {
      int px = j * gridWidth - 9;
      int py = 1 * gridHeight - 9;
      int rgb = image.getRGB(px, py);
      current = TetraminoFactory.getIndexByRBG(rgb);
      System.out.println("getCurrent" + rgb);
      if (current != -1) {
        break;
      }
    }
    if(current == -1){
    	System.out.println(new Color(current));
    }
  }

  private void getNext() {
    int t = -1;
    t = TetraminoFactory.getIndexByRBG(robot.getPixelColor(nextPoint1.x, nextPoint1.y).getRGB());
    if (t == -1) {
      t = TetraminoFactory.getIndexByRBG(robot.getPixelColor(nextPoint2.x, nextPoint2.y).getRGB());
      if (t == -1) {
        t = TetraminoFactory.getIndexByRBG(robot.getPixelColor(nextPoint3.x, nextPoint3.y).getRGB());
      }
    }
    if (t != -1) {
      next = t;
    } else {
      System.out.println("not recognized");
      System.exit(0);
    }
  }

  private void getBoard() {
    BufferedImage image = robot.createScreenCapture(rect);
//    System.out.println("------------------");
    for (int i = 1, x = 19; i < 21; i++, x--) {
      String rowStr = "";
      for (int j = 1; j < 11; j++) {
        if (image != null) {
          int px = j * gridWidth - 9;
          int py = i * gridHeight - 9;

          int rgb = image.getRGB(px, py);

          if (rgb == lightBlack || rgb == darkBlack
                  || rgb == lightestBlack) {
            rowStr += "0";
          } else {
            rowStr += "1";
          }
        }

      }
      if (x != 19) {
        board[x] = Integer.parseInt(new StringBuffer(rowStr).reverse().toString(), 2);
      } else {
        board[x] = 0;
      }
//      System.out.println(rowStr);
    }
//    System.out.println("------------------");
  }

  private void sendingPiece() {

    if (current == -1) {
      getCurrent();
      getNext();
      sendShift();
    } else {
      Move move1;
      Move move2;
      getCurrent();
      System.out.println("current " + TetraminoFactory.getNameByIndex(current));
      System.out.println("next " + TetraminoFactory.getNameByIndex(next));
      getBoard();
//      if (pressedShift == false) {
//        move1 = bot.move(new Board(board, 19, 10), current);
//        move2 = bot.move(new Board(board, 19, 10), hold);
//
//        if (move1 != null && move2 != null && move1.getScore() >= move2.getScore()) {
//          finalMove = move1;
//        } else {
//          sendShift();
//          finalMove = move2;
//        }
//      } else {
//      System.out.println(Arrays.toString(lastBoard));
//      System.out.println(Arrays.toString(board));
      if (lastBoard != null && !Arrays.equals(board, lastBoard)) {
        System.out.println("not equal");
        System.exit(0);
      }
      currentMove = bot.move(new Board(board, 19, 10), current);
      lastBoard = currentMove.getResultingBoard().getData();
      System.out.println("finalmove: " + currentMove);
//      getNext();
      //rotate
      int rotation = currentMove.getRotation();

      while (rotation > 0) {
        sendRotate();
        rotation--;
      }

      int column = currentMove.getColumn();
      int offset = column - currentMove.getTetramino().getOffset();

      if (offset > 0) {
        while (offset > 0) {
          sendRight();
          offset--;
        }
      } else if (offset < 0) {
        while (offset < 0) {
          sendLeft();
          offset++;
        }
      }
      sendSpace();
      
      if(currentMove.getRowsRemoved() > 0){
    	  robot.delay(100);
      }
    }
  }

  private void sendSpace() {
//    current = next;
    robot.keyPress(KeyEvent.VK_SPACE);
    robot.delay(70);
    robot.keyRelease(KeyEvent.VK_SPACE);
    robot.delay(70);
    pressedShift = false;

  }

  private void sendLeft() {

    robot.keyPress(KeyEvent.VK_LEFT);
    robot.delay(60);
    robot.keyRelease(KeyEvent.VK_LEFT);
    robot.delay(60);
  }

  private void sendRight() {

    robot.keyPress(KeyEvent.VK_RIGHT);
    robot.delay(60);
    robot.keyRelease(KeyEvent.VK_RIGHT);
    robot.delay(60);
  }

  private void sendRotate() {

    robot.keyPress(KeyEvent.VK_UP);
    robot.delay(70);
    robot.keyRelease(KeyEvent.VK_UP);
    robot.delay(70);
  }

  private void sendShift() {
    hold = current;
    current = next;
    pressedShift = true;
    robot.keyPress(KeyEvent.VK_SHIFT);
    robot.delay(60);
    robot.keyRelease(KeyEvent.VK_SHIFT);
    robot.delay(60);
//    System.out.println("sendShift");

  }

  public int getDelay() {
    return delay;
  }

  public void setDelay(int delay) {
    this.delay = delay;
  }

  public Bot getBot() {
    return bot;
  }

  public void setBot(Bot bot) {
    this.bot = bot;
  }

  private enum State {

    STANDBY,
    SENDING_PIECE,}
}